#ifndef CLIST_H
#define CLIST_H

#include "CNode.h"
#include "typedef.h"
#include <list>

class CList
{
public:
   CList() {}
   ~CList() {}

   void insert(CNode * pNode);

   CNode * getAndRemoveBest();

   CNode * get(const key & key);

   void push_back(CNode * pNode);

   CNode * back();

   void releaseHeap();

   inline bool empty() const;

protected:
   std::list<CNode *> mList;
};

void CList::insert(CNode * pNode)
{
   if(pNode != NULL)
   {
      std::list<CNode *>::iterator insertPos = mList.begin();
      std::list<CNode *>::iterator end = mList.end();
      while(insertPos != end)
      {
         cost currentCost = pNode->getCost();
         cost ExistCost = (*insertPos)->getCost();
         if(currentCost < ExistCost)
         {
            break;
         }
         ++insertPos;
      }
      mList.insert(insertPos, pNode);
      pNode->addRef();
   }
}

CNode * CList::getAndRemoveBest()
{
   CNode * pBest = NULL;
   if(!mList.empty())
   {
      pBest = mList.front();
      mList.pop_front();
   }
   return pBest;
}

CNode * CList::get(const key & k)
{
   std::list<CNode *>::iterator find = mList.begin();
   std::list<CNode *>::iterator end = mList.end();
   while(find != end)
   {
      if((*find)->id() == k)
      {
         break;
      }
      ++find;
   }
   return find != end ? *find : NULL;
}

void CList::push_back(CNode * pNode)
{
   if(pNode != NULL)
   {
      mList.push_back(pNode);
      pNode->addRef();
   }
}

CNode * CList::back()
{
   CNode * pBack = NULL;
   if(!mList.empty())
   {
      pBack = mList.back();
   }
   return pBack;
}

void CList::releaseHeap()
{
   std::list<CNode *>::iterator pos = mList.begin();
   std::list<CNode *>::iterator end = mList.end();
   while(pos != end)
   {
      (*pos)->release();
      ++pos;
   }
}

inline bool CList::empty() const
{
   return mList.empty();
}
#endif//CLIST_H